/*********************************************************************************************************************
* MM32F527X-E9P Opensource Library 即（MM32F527X-E9P 开源库）是一个基于官方 SDK 接口的第三方开源库
* Copyright (c) 2022 SEEKFREE 逐飞科技
* 
* 本文件是 MM32F527X-E9P 开源库的一部分
* 
* MM32F527X-E9P 开源库 是免费软件
* 您可以根据自由软件基金会发布的 GPL（GNU General Public License，即 GNU通用公共许可证）的条款
* 即 GPL 的第3版（即 GPL3.0）或（您选择的）任何后来的版本，重新发布和/或修改它
* 
* 本开源库的发布是希望它能发挥作用，但并未对其作任何的保证
* 甚至没有隐含的适销性或适合特定用途的保证
* 更多细节请参见 GPL
* 
* 您应该在收到本开源库的同时收到一份 GPL 的副本
* 如果没有，请参阅<https://www.gnu.org/licenses/>
* 
* 额外注明：
* 本开源库使用 GPL3.0 开源许可证协议 以上许可申明为译文版本
* 许可申明英文版在 libraries/doc 文件夹下的 GPL3_permission_statement.txt 文件中
* 许可证副本在 libraries 文件夹下 即该文件夹下的 LICENSE 文件
* 欢迎各位使用并传播本程序 但修改内容时必须保留逐飞科技的版权声明（即本声明）
* 
* 文件名称          zf_device_spi_tfcard
* 公司名称          成都逐飞科技有限公司
* 版本信息          查看 libraries/doc 文件夹内 version 文件 版本说明
* 开发环境          MDK 5.37
* 适用平台          MM32F527X_E9P
* 店铺链接          https://seekfree.taobao.com/
* 
* 修改记录
* 日期              作者                备注
* 2022-08-10        Teternal            first version
********************************************************************************************************************/

#ifndef _zf_device_spi_tfcard_h_
#define _zf_device_spi_tfcard_h_

#include "zf_common_typedef.h"

#define TFCARD_USE_SOFT_SPI             ( 0 )                                   // 默认使用硬件 SPI 方式驱动 建议使用硬件 SPI 方式驱动
#if TFCARD_USE_SOFT_SPI                                                         // 这两段 颜色正常的才是正确的 颜色灰的就是没有用的
//====================================================软件 SPI 驱动====================================================
#define TFCARD_SOFT_SPI_DELAY           ( 1  )                                  // 软件 SPI 的时钟延时周期 数值越小 SPI 通信速率越快
#define TFCARD_SCK_PIN                  ( C10 )                                 // 软件 SPI SCK 引脚
#define TFCARD_MISO_PIN                 ( C11 )                                 // 软件 SPI MISO 引脚
#define TFCARD_MOSI_PIN                 ( C12 )                                 // 软件 SPI MOSI 引脚
//====================================================软件 SPI 驱动====================================================
#else
//====================================================硬件 SPI 驱动====================================================
#define TFCARD_SPI_INIT_SPEED           ( 400 * 1000 )                          // 硬件 SPI 速率 这里设置为系统时钟二分频
#define TFCARD_SPI_WORK_SPEED           ( 20 * 1000 * 1000 )                    // 硬件 SPI 速率 这里设置为系统时钟二分频
#define TFCARD_SPI                      ( SPI_3            )                    // 硬件 SPI 号
#define TFCARD_SCK_PIN                  ( SPI3_SCK_C10     )                    // 硬件 SPI SCK 引脚
#define TFCARD_MISO_PIN                 ( SPI3_MISO_C11    )                    // 硬件 SPI MISO 引脚
#define TFCARD_MOSI_PIN                 ( SPI3_MOSI_C12    )                    // 硬件 SPI MOSI 引脚
//====================================================硬件 SPI 驱动====================================================
#endif
#define TFCARD_CS_PIN                   ( A15 )                                 // CS 引脚
#define TFCARD_CS(x)                    ((x) ? (gpio_high(TFCARD_CS_PIN)) : (gpio_low(TFCARD_CS_PIN)))

// TF卡类型定义
typedef enum {
    TFCARD_TYPE_ERROR   = ( 0x00 ),
    TFCARD_TYPE_MMC     = ( 0x01 ),
    TFCARD_TYPE_SDV1    = ( 0x02 ),
    TFCARD_TYPE_SDV2    = ( 0x04 ),
    TFCARD_TYPE_SDHC    = ( 0x06 ),
    TFCARD_TYPE_SDXC    = ( 0x08 ),
}tfcard_type_enum;

// TF卡指令表 
typedef enum{ 	   
    TFCARD_CMD0         = ( 0  ),                                               // 命令 0  SD卡 进入空闲状态
    TFCARD_CMD1         = ( 1  ),                                               // 命令 1  SD卡 进入工作状态
    TFCARD_CMD6         = ( 6  ),                                               // 命令 6  SD卡 进入高速模式 50MHz
    TFCARD_CMD8         = ( 8  ),                                               // 命令 8  SEND_IF_COND
    TFCARD_CMD9         = ( 9  ),                                               // 命令 9  读 CSD 数据
    TFCARD_CMD10        = ( 10 ),                                               // 命令 10 读 CID 数据
    TFCARD_CMD12        = ( 12 ),                                               // 命令 12 停止数据传输
    TFCARD_CMD13        = ( 13 ),                                               // 命令 13 读状态
    TFCARD_CMD16        = ( 16 ),                                               // 命令 16 设置块大小 应返回 0x00
    TFCARD_CMD17        = ( 17 ),                                               // 命令 17 读单个扇区
    TFCARD_CMD18        = ( 18 ),                                               // 命令 18 读多个扇区
    TFCARD_CMD23        = ( 23 ),                                               // 命令 23 设置多 sector 写入前预先擦除 N 个 block
    TFCARD_CMD24        = ( 24 ),                                               // 命令 24 写单个扇区
    TFCARD_CMD25        = ( 25 ),                                               // 命令 25 写多个扇区
    TFCARD_CMD32        = ( 32 ),                                               // 命令 32 设置要擦除的起始地址
    TFCARD_CMD33        = ( 33 ),                                               // 命令 33 设置要擦除的结束地址
    TFCARD_CMD38        = ( 38 ),                                               // 命令 38 擦除指定区间的内容
    TFCARD_CMD41        = ( 41 ),                                               // 命令 41 应返回 0x00
    TFCARD_CMD55        = ( 55 ),                                               // 命令 55 应返回 0x01
    TFCARD_CMD58        = ( 58 ),                                               // 命令 58 读 OCR 信息
    TFCARD_CMD59        = ( 59 ),                                               // 命令 59 使能/禁止 CRC 应返回 0x00
}tfcard_cmd_enum;

// 数据写入回应字意义
#define TFCARD_MSD_DATA_OK                  ( 0x05 )
#define TFCARD_MSD_DATA_CRC_ERROR           ( 0x0B )
#define TFCARD_MSD_DATA_WRITE_ERROR         ( 0x0D )
#define TFCARD_MSD_DATA_OTHER_ERROR         ( 0xFF )

// TF 卡回应标记字
#define TFCARD_MSD_RESPONSE_NO_ERROR        ( 0x00 )
#define TFCARD_MSD_IN_IDLE_STATE            ( 0x01 )
#define TFCARD_MSD_ERASE_RESET              ( 0x02 )
#define TFCARD_MSD_ILLEGAL_COMMAND          ( 0x04 )
#define TFCARD_MSD_COM_CRC_ERROR            ( 0x08 )
#define TFCARD_MSD_ERASE_SEQUENCE_ERROR     ( 0x10 )
#define TFCARD_MSD_ADDRESS_ERROR            ( 0x20 )
#define TFCARD_MSD_PARAMETER_ERROR          ( 0x40 )
#define TFCARD_MSD_RESPONSE_FAILURE         ( 0xFF )

/* SD卡信息 */
#pragma pack(1)
typedef struct
{
  uint8             tfcard_cid[16];
  uint8             tfcard_csd[16];
  uint8             tfcard_speed;
  tfcard_type_enum  tfcard_type;
  uint32            tfcard_sector_max;
  uint32            tfcard_capacity_kbyte;
}tfcard_information_struct;
#pragma pack()

extern tfcard_information_struct tfcard_information;

uint8       tfcard_get_response             (uint8 response);
uint8       tfcard_send_cmd                 (uint8 cmd, uint32 arg, uint8 crc);
uint8       tfcard_get_state                (void);

uint8       tfcard_read_data                (uint8 *buff, uint32 len);
uint8       tfcard_write_block              (uint8 *buff, uint8 cmd);

uint8       tfcard_enter_idlemode           (void);
uint8       tfcard_enter_high_speed_mode    (void);

uint8       tfcard_read_sector              (uint8 *buff, uint32 sector, uint32 cnt);
uint8       tfcard_write_sector             (uint8 *buff, uint32 sector, uint32 cnt);

void        tfcard_information_printf       (void);
uint8       tfcard_init                     (void);

#endif
